/**
 * &copy; 2006 NewInstance.it
 */
package it.newinstance.jrainbow.source;

/**
 * @author Luigi R. Viggiano
 * @version $Id: TaggedChar.java 153 2007-06-22 00:12:48Z luigi.viggiano $
 */
public class TaggedChar {
    private static final TaggedChar NULL = new TaggedChar('\0');

    private char chr;
    private Tag tag;
    private TaggedChar previous = NULL;
    private TaggedChar next = NULL;

    public TaggedChar(char chr) {
        this.chr = chr;
    }

    public char getChar() {
        return chr;
    }

    public Tag getTag() {
        return tag;
    }

    public void setTag(Tag tag) {
        this.tag = tag;
    }

    public void setPrevious(TaggedChar previous) {
        this.previous = previous;
        if (previous.next == NULL)
            previous.next = this;
    }

    public void setNext(TaggedChar next) {
        this.next = next;
        if (next.previous == NULL)
            next.previous = this;
    }

    public TaggedChar getNext() {
        return next;
    }
    
    public TaggedChar getNext(int count) {
        TaggedChar result = this;
        for (int i = 0; i < count; i++)
            result = result.getNext();
        return result;
    }    

    public TaggedChar getPrevious() {
        return previous;
    }

    /**
     * Match last chars with the given string.
     * @param string the string to be matched
     * @return true if the string matches, false otherwise
     */
    public boolean match(String string) {
        TaggedChar current = this;
        int i = string.length() - 1;
        while (i >= 0) {
            char ch = string.charAt(i);
            if (ch != current.getChar())
                return false;
            current = current.getPrevious();
            i--;
        }
        return true;
    }

    /**
     * Tags count chars forward/backward from current. Negative count means to 
     * count backward.
     * 
     * @param tag the tag
     * @param count the number of chars to tag (negative means backward)
     */
    public void setTag(Tag tag, int count) {
        if (count == 0) return;
        TaggedChar currentChar = this;
        if (count > 0) {
            for (int i = 0; i < count ; i++) {
                currentChar.setTag(tag);
                currentChar = currentChar.getNext();
            }
        } else {
            for (int i = count; i < 0; i++) {
                currentChar.setTag(tag);
                currentChar = currentChar.getPrevious();
            }
        }
    }
}
